package org.zjx.app.action.route;

import org.zjx.analysis.analyze.flag.*;
import org.zjx.analysis.analyze.game.GameAnalysis;
import org.zjx.analysis.analyze.window.impl.InventorAnalysis;
import org.zjx.app.action.AbstractWindowAction;
import org.zjx.command.entity.ItemInstance;
import org.zjx.command.entity.screen.Address;
import org.zjx.command.enums.SlotType;
import org.zjx.command.state.ItemState;
import org.zjx.window.window.IWindow;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;

//使用飞行符
public class        FlyingFlagAction extends AbstractWindowAction {
    private InventorAnalysis inventorAnalysis;
    private BaseFlagAnalysis baseFlagAnalysis;
    private final Address targetAddress;

    public FlyingFlagAction(IWindow targetWindow, Address targetAddress) {
        super(targetWindow, false);
        this.targetAddress = targetAddress;
    }

    @Override
    protected void doExecute() throws Exception {
        if (!getAddressNow().near(targetAddress, 5)) {
            useFlyingFlag();
        }
    }

    private void useFlyingFlag() {
        open();
        reSetWindow();
        int index = getInventorArea();
        if (index == -1) {
            //TODO 需要购买飞行符了
            throw new IllegalArgumentException("合成旗不存在！！！");
        } else {
            Rectangle flyingArea = inventorAnalysis.getItemIndexArea(index);
            do {
                targetWindow.actions().gameMoveTo(flyingArea.getCenterX(),flyingArea.getCenterY()).delay(50).click(2).delay(500);
                targetWindow.flushScreenshot();
                analysisFlyingFlag();
            } while (!baseFlagAnalysis.isOpened());

            Point getLocation = baseFlagAnalysis.getLocation(new Point(targetAddress.getX(), targetAddress.getY()));

            do {
                targetWindow.actions().clickAt(getLocation.x,getLocation.y).delay(500);
                targetWindow.flushScreenshot();
                analysisFlyingFlag();
            } while (baseFlagAnalysis.isOpened());
        }

        close();
    }

    //获取飞行符所在位置
    private int getInventorArea() {
        List<ItemInstance> itemInstances = stateManager.getState(ItemState.class).getItemsByType(SlotType.INVENTORY);
        for (int i = 0; i < itemInstances.size(); i++) {
            ItemInstance itemInstance = itemInstances.get(i);
            if (itemInstance == null) continue;
            if (isValidFlag(itemInstance)) return i;
        }
        return -1;
    }

    /**
     * 检查是否为有效的合成旗
     */
    private boolean isValidFlag(ItemInstance instance) {
        return instance != null &&
                instance.getName().contains("合成旗") &&
                instance.getAttributes() != null &&
                instance.getAttributes().containsKey("场景") &&
                instance.getAttributes().get("场景").equals(targetAddress.getCity());
    }

    private void analysis() {
        inventorAnalysis = new InventorAnalysis(targetWindow);
    }

    private void analysisFlyingFlag() {
        switch (targetAddress.getCity()) {
            case "长安城":
                baseFlagAnalysis = new FlagsCACAnalysis(targetWindow);
                break;
            case "傲来国":
                baseFlagAnalysis = new FlagsALGAnalysis(targetWindow);
                break;
            case "长寿村":
                baseFlagAnalysis = new FlagsCSCAnalysis(targetWindow);
                break;
            case "朱紫国":
                baseFlagAnalysis = new FlagsZZGAnalysis(targetWindow);
                break;
            default:
                throw new IllegalArgumentException("合成旗城市未收录:" + targetAddress.getCity());
        }
    }

    @Override
    public void open() {
        analysis();
        mouseAloofWindow(inventorAnalysis.windowArea == null? inventorAnalysis.getOriginBounds(): inventorAnalysis.windowArea);
        if (inventorAnalysis.isOpened()) return;
        targetWindow.actions().hotkey(KeyEvent.VK_ALT, KeyEvent.VK_E).delay(500);
        targetWindow.flushScreenshot();
        analysis();
        open();
    }

    @Override
    public void close() {
        analysis();
        if (!inventorAnalysis.isOpened()) return;
        targetWindow.actions().hotkey(KeyEvent.VK_ALT, KeyEvent.VK_E).delay(500);
        targetWindow.flushScreenshot();
        mouseAloofWindow(inventorAnalysis.windowArea == null? inventorAnalysis.getOriginBounds(): inventorAnalysis.windowArea);
        close();
    }

    @Override
    public void reSetWindow() {
        if (inventorAnalysis.isTransborder()) {
            Rectangle from = inventorAnalysis.conversion(inventorAnalysis.windowArea,inventorAnalysis.getRefImageArea());
            Rectangle to = inventorAnalysis.conversion(inventorAnalysis.getOriginBounds(),inventorAnalysis.getRefImageArea());
            targetWindow.actions().drag(from.x, from.y, to.x, to.y).delay(100);
            targetWindow.flushScreenshot();
            analysis();
        }
    }

    @Override
    public void mouseAloofWindow(Rectangle rect) {
        if (inventorAnalysis.mouseInRect(rect)) {
            Point safePoint = inventorAnalysis.findLargestRemainingAreaCenter(rect);
            targetWindow.actions().gameMoveTo(safePoint.x, safePoint.y).delay(200);
            targetWindow.flushScreenshot();
            analysis();
        }
    }

    public Address getAddressNow() {
        GameAnalysis gameAnalysis = new GameAnalysis(targetWindow);
        return gameAnalysis.getAddress();
    }
}
